use config::{Config as ConfigBuilder, File};
use rust_test::common::*;
use serde::{Deserialize, Serialize};

#[mydbginfo]
pub fn tt() -> Result<(), Box<dyn std::error::Error>> {
    // 反序列化
    tt1();
    // 序列化
    tt2();
    // 反序列化
    tt3();
    // 反序列化
    tt4();

    Ok(())
}

#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(default)]
struct MyConfig {
    #[serde(default)]
    ip: String,
    #[serde(default)]
    port: Option<u16>,
    #[serde(default)]
    keys: MyKeys,
    #[serde(default)]
    val: f64,
    #[serde(default)]
    myf64: MyF64,
}

#[derive(Debug, Serialize, Deserialize)]
struct MyF64(f64);
impl Default for MyF64 {
    fn default() -> Self {
        Self(123.654)
    }
}

#[derive(Debug, Serialize, Deserialize, Default)]
struct MyKeys {
    #[serde(default)]
    github: String,
    #[serde(default)]
    travis: Option<String>,
}

#[mydbginfo]
pub fn tt1() {
    let config: MyConfig = toml::from_str(
        r#"
ip = '127.0.0.1'
val = 300.0
[keys]
github = 'xxxxxxxxxxxxxxxxx'
travis = 'yyyyyyyyyyyyyyyyy'
"#,
    )
    .unwrap();

    println!("the deserialize config: {:#?}: ", config);
}

#[mydbginfo]
pub fn tt2() {
    let config = MyConfig {
        ip: "127.0.0.1".to_string(),
        val: 300.0,
        myf64: MyF64(77.889),
        port: None,
        keys: MyKeys {
            github: "xxxxxxxxxxxxxxxxx".to_string(),
            travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
        },
    };

    let toml = toml::to_string(&config).unwrap();
    println!("the serialize {}: ", toml);
}

#[mydbginfo]
pub fn tt3() {
    let config: MyConfig = toml::from_str(
        r#"
ip = '127.0.0.1'
[keys]
github = 'xxxxxxxxxxxxxxxxx'
travis = 'yyyyyyyyyyyyyyyyy'
"#,
    )
    .unwrap();
    println!("the deserialize config: {:#?}", config);

    let config2: MyConfig = toml::from_str(
        r#"
ip = '127.0.0.1'
[keys]
"#,
    )
    .unwrap();
    println!("\nthe deserialize config2: {:#?}", config2);
}

#[mydbginfo]
pub fn tt4() {
    // 构建配置并获取 Config 实例
    let config_instance = ConfigBuilder::builder()
        .add_source(File::from_str(
            r#"
ip = '127.0.0.1'
[keys]
github = 'xxxxxxxxxxxxxxxxx'
travis = 'yyyyyyyyyyyyyyyyy'
"#,
            config::FileFormat::Toml,
        ))
        .build()
        .unwrap();

    // 在 Config 实例上调用 try_deserialize
    let config: MyConfig = config_instance.try_deserialize().unwrap();
    println!("the deserialize config: {:#?}", config);
}
